﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Economic.Api.Client;
using Economic.Api.Data;
using Economic.Api.Exceptions;
using Economic.Api;
using System.Configuration;
using System.IO;

namespace TireService.Data
{
    public class EconomicInterface
    {
        EconomicSession _session = null;
        string EconomicApiLog;

        /// <summary>
        /// Function that establish connect to E-conomic
        /// </summary>
        /// <returns></returns>
        private string Connect()
        {
            //if (!Convert.ToBoolean(Convert.ToByte(ConfigurationSettings.AppSettings["EcoInterfaceActive"])))
            //{
            //    // Interface not active
            //    throw new ArgumentException("Interface ikke aktiveret.");
            //}

            EconomicApiLog = "Connecting.." + "\n";
            return _session.Connect(Int32.Parse(ConfigurationSettings.AppSettings["EcoAgreementNumber"]), ConfigurationSettings.AppSettings["EcoUsername"], ConfigurationSettings.AppSettings["EcoPassword"]);
        }

        /// <summary>
        /// Function that disconnect from E-conomic
        /// </summary>
        private void Disconnect()
        {
            EconomicApiLog += "\n" + "Disconnecting..";
            _session.Disconnect();
        }

        private int UpdateInterfaceQueue(int Object, int Action, int? ObjectPrimaryKeyValue, string Note)
        {
            //TireServiceDB db = new TireServiceDB();

            //EconomicInterfaceQueue queue = new EconomicInterfaceQueue();

            //// Check if action in interface queue already exists
            //queue = db.EconomicInterfaceQueues.SingleOrDefault(p => p.Object == (int)Object & p.Action == (int)Action & p.Rundate == null & p.ObjectPrimaryKeyValue == (int)ObjectPrimaryKeyValue);

            //if (queue == null)
            //{
            //    queue.Object = Object;
            //    queue.Action = Action;
            //    queue.ObjectPrimaryKeyValue = Convert.ToInt32(ObjectPrimaryKeyValue);
            //    queue.Note = Note;

            //    db.EconomicInterfaceQueues.InsertOnSubmit(queue);

            //    db.SubmitChanges();
            //}

            //int queueid = queue.QueueId;

            //db.Dispose();

            //return queueid;
            return 0;
        }

        private bool InterfaceQueueCompleted(int QueueId, string Note)
        {
            //TireServiceDB db = new TireServiceDB();

            //EconomicInterfaceQueue queue = new EconomicInterfaceQueue();

            //// Check if action in interface queue already exists
            //queue = db.EconomicInterfaceQueues.SingleOrDefault(p => p.QueueId == QueueId);

            //bool queuerun = false;

            //if (queue == null)
            //{
            //    queue.Rundate = DateTime.Now;
            //    queuerun = true;
            //}
            //else
            //{
            //    // TODO: Write email with error to system admin with log
            //}

            //queue.Note = Note;

            //db.SubmitChanges();

            //db.Dispose();

            //return queuerun;
            return true;
        }

        public void CreateDebtor(Customer customer, TireServiceDB db)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;
                
                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Debtor, (int)Shared.EconomicInterfaceActions.CreateObject, customer.CustomerId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Create new debtor
                IDebtorGroup DebtorGroup = _session.DebtorGroup.FindByNumber(Int32.Parse(ConfigurationSettings.AppSettings["EcoDebtorGroupNumber"]));
                if (DebtorGroup == null) throw new Exception("Ingen debitorgruppe fundet");

                // Set currency
                //ICurrency currency = _session.Currency.FindByCode("DKK");
                //if (currency == null) throw new Exception("Valuta ikke fundet");
                
                //IDebtorData debtor = _session.DebtorData.Create(customer.CustomerId.ToString(), DebtorGroup, customer.CompanyName ?? customer.Name, VatZone.HomeCountry);
                IDebtor debtor = _session.Debtor.Create(customer.CustomerId.ToString(), DebtorGroup, customer.CompanyName ?? customer.Name, VatZone.HomeCountry);
                debtor.IsAccessible = true;
                debtor.Address = customer.Address;
                debtor.City = customer.City;
                debtor.PostalCode = customer.ZipCode;
                debtor.Country = db.GetCountryName(customer.CountryId);
                debtor.TelephoneAndFaxNumber = customer.Phone1;
                debtor.Email = customer.Email;
                //debtor.Currency = currency;
                
                //_session.Debtor.CreateFromData(debtor);

                //_session.Debtor.Create(CustomerId.ToString(), DebtorGroup, Name, VatZone.HomeCountry);
                EconomicApiLog += "\r\n" + "Debitor oprettet";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {
                EconomicApiLog += "\r\n" + ex.Message;
            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        public void UpdateDebtor(Customer customer, TireServiceDB db)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Debtor, (int)Shared.EconomicInterfaceActions.UpdateObject, customer.CustomerId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Update debtor
                IDebtor debtor = _session.Debtor.FindByNumber(customer.CustomerId.ToString());
                if (debtor == null)
                {
                    // Debtor not found - create debtor
                    CreateDebtor(customer, db);
                }
                else
                {
                    debtor.IsAccessible = true;
                    if (customer.IsCompany)
                    {
                        debtor.Name = customer.CompanyName;
                    }
                    else
                    {
                        debtor.Name = customer.Name;
                    }
                    debtor.Address = customer.Address;
                    debtor.City = customer.City;
                    debtor.PostalCode = customer.ZipCode;
                    debtor.Country = db.GetCountryName(customer.CountryId);
                    debtor.TelephoneAndFaxNumber = customer.Phone1;
                    debtor.Email = customer.Email;
                    EconomicApiLog += "\r\n" + "Debitor data vedligeholdt";
                }

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {
                EconomicApiLog += "\r\n" + ex.Message;
                
            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        public void UpdateDebtorBasedOnEconomic(Customer customer, TireServiceDB db, bool SubmitInTransaction) 
        {
            // Start session
            _session = new EconomicSession();

            //connect
            string connectMessage = Connect();
            EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

            // Create EconomicInterfaceQueue record
            int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Debtor, (int)Shared.EconomicInterfaceActions.UpdateObject, customer.CustomerId, "Webhook - synkronisering med E-conomic");

            //get API version.
            EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

            // Get debtor
            IDebtor debtor = _session.Debtor.FindByNumber(customer.CustomerId.ToString());

            if (customer.IsCompany)
            {
                customer.CompanyName = debtor.Name;
            }
            else
            {
                customer.Name = debtor.Name;
            }
            customer.Address = debtor.Address;
            customer.City = debtor.City;
            customer.ZipCode = debtor.PostalCode;
            //debtor.Country = db.getcount.GetCountryName(customer.CountryId);
            customer.Phone1 = debtor.TelephoneAndFaxNumber;
            customer.Email = debtor.Email;
            EconomicApiLog += "\r\n" + "Debitor data synkroniseret med E-conomic";

            // Check if customer is being updated in other transaction
            if (!SubmitInTransaction)
            {
                // Submit changes to database
                db.SubmitChanges();
            }

            // Mark interface queue as run with ApiLog as note
            InterfaceQueueCompleted(QueueId, EconomicApiLog);
        }

        /// <summary>
        /// Function that creates subscription for a subscriber
        /// </summary>
        /// <param name="EconomicSubscriptionNumber"></param>
        /// <param name="customersubscription"></param>
        public void CreateSubscriber(int EconomicSubscriptionNumber, CustomerSubscription customersubscription, int? ParentCustomerId, string ContactName)
        {
            try
            {
                // Check if subscription is single subscription (and thereby not reaccuring)
                if (EconomicSubscriptionNumber == 4)
                {
                    return;
                }

                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.CustomerSubscription, (int)Shared.EconomicInterfaceActions.CreateObject, customersubscription.CustomerSubscriptionId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(customersubscription.CustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Create new subscriber
                ISubscription subscription = _session.Subscription.FindByNumber(EconomicSubscriptionNumber);
                ISubscriber subscriber = _session.Subscriber.Create(debtor, subscription, customersubscription.LastRenewalDate, customersubscription.Createdate, customersubscription.NextRenewalDate);
                subscriber.SpecialPrice = (customersubscription.Price * Convert.ToDecimal(0.8));
                subscriber.Comments = "Kontakt: " + ContactName;
                
                // Add key to identify subscriber in e-conomic
                subscriber.ExtraTextForInvoice = "Abonnement nr: " + customersubscription.CustomerSubscriptionId.ToString(); 

                EconomicApiLog += "\r\n" + "Abonnent oprettet";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        /// <summary>
        /// Function that updates subscription for a specific subscriber
        /// </summary>
        /// <param name="EconomicSubscriptionNumber"></param>
        /// <param name="customersubscription"></param>
        public void UpdateSubscriber(int EconomicSubscriptionNumber, CustomerSubscription customersubscription, int? ParentCustomerId, string ContactName)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;
                
                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.CustomerSubscription, (int)Shared.EconomicInterfaceActions.UpdateObject, customersubscription.CustomerSubscriptionId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor (either parent customer or customer)
                IDebtor debtor = _session.Debtor.FindByNumber(Convert.ToString(ParentCustomerId ?? customersubscription.CustomerId));
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Get subscription and subscriber
                ISubscription subscription = _session.Subscription.FindByNumber(EconomicSubscriptionNumber);
                ISubscriber subscriber = debtor.GetSubscribers().SingleOrDefault(p => p.ExtraTextForInvoice.Replace("Abonnement nr: ", "") == customersubscription.CustomerSubscriptionId.ToString());
                if (subscriber == null)
                {
                    // Subscriber not found - create subscriber
                    CreateSubscriber(EconomicSubscriptionNumber, customersubscription, ParentCustomerId, ContactName);
                }
                else
                {
                    EconomicApiLog += "\r\n" + "Abonnent hentet";

                    // Update subscriber
                    subscriber.StartDate = customersubscription.LastRenewalDate;
                    subscriber.EndDate = customersubscription.NextRenewalDate;
                    subscriber.SpecialPrice = (customersubscription.Price * Convert.ToDecimal(0.8));
                    subscriber.Comments = "Kontakt: " + ContactName;

                    EconomicApiLog += "\r\n" + "Abonnent opdateret";
                }

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        /// <summary>
        /// Function that expire/inactivate subscription for a specific subscriber
        /// </summary>
        /// <param name="EconomicSubscriptionNumber"></param>
        /// <param name="customersubscription"></param>
        public void ExpireSubscriber(int EconomicSubscriptionNumber, CustomerSubscription customersubscription)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;
                
                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.CustomerSubscription, (int)Shared.EconomicInterfaceActions.UpdateObject, customersubscription.CustomerSubscriptionId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(customersubscription.CustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                ISubscription subscription = _session.Subscription.FindByNumber(EconomicSubscriptionNumber);
                ISubscriber subscriber = debtor.GetSubscribers().SingleOrDefault(p => p.ExtraTextForInvoice.Replace("Abonnement nr: ", "") == customersubscription.CustomerSubscriptionId.ToString());
                EconomicApiLog += "\r\n" + "Abonnent hentet";

                // Expire subscriber
                subscriber.ExpiryDate = customersubscription.InActiveDate;

                EconomicApiLog += "\r\n" + "Abonnent lukket";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        /// <summary>
        /// Function that reactive subscription for a specific subscriber
        /// </summary>
        /// <param name="EconomicSubscriptionNumber"></param>
        /// <param name="customersubscription"></param>
        public void ReActivateSubscriber(int EconomicSubscriptionNumber, CustomerSubscription customersubscription)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.CustomerSubscription, (int)Shared.EconomicInterfaceActions.UpdateObject, customersubscription.CustomerSubscriptionId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(customersubscription.CustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                ISubscription subscription = _session.Subscription.FindByNumber(EconomicSubscriptionNumber);
                ISubscriber subscriber = debtor.GetSubscribers().SingleOrDefault(p => p.ExtraTextForInvoice.Replace("Abonnement nr: ", "") == customersubscription.CustomerSubscriptionId.ToString());
                EconomicApiLog += "\r\n" + "Abonnent hentet";

                // ReActivate subscriber
                subscriber.ExpiryDate = null;
                subscriber.StartDate = customersubscription.LastRenewalDate;
                subscriber.EndDate = customersubscription.NextRenewalDate;
                subscriber.SpecialPrice = (customersubscription.Price * Convert.ToDecimal(0.8));

                EconomicApiLog += "\r\n" + "Abonnent genaktiveret";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        /// <summary>
        /// Function that change subscription for one subscriber to another subscription
        /// </summary>
        /// <param name="EconomicSubscriptionNumber"></param>
        /// <param name="NewEconomicSubscriptionNumber"></param>
        /// <param name="customersubscription"></param>
        public void ChangeSubscriberSubscription(int EconomicSubscriptionNumber, int NewEconomicSubscriptionNumber, CustomerSubscription customersubscription)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;
                
                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.CustomerSubscription, (int)Shared.EconomicInterfaceActions.UpdateObject, customersubscription.CustomerSubscriptionId, null);

                // Get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(customersubscription.CustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Get subscription and subscriber
                ISubscription subscription = _session.Subscription.FindByNumber(EconomicSubscriptionNumber);
                ISubscription newsubscription = _session.Subscription.FindByNumber(NewEconomicSubscriptionNumber);
                ISubscriber subscriber = debtor.GetSubscribers().SingleOrDefault(p => p.ExtraTextForInvoice.Replace("Abonnement nr: ", "") == customersubscription.CustomerSubscriptionId.ToString());
                EconomicApiLog += "\r\n" + "Abonnent hentet";

                // Change subscription type and update subscriber
                subscriber.ExpiryDate = null;
                subscriber.StartDate = customersubscription.LastRenewalDate;
                subscriber.EndDate = customersubscription.NextRenewalDate;
                subscriber.SpecialPrice = (customersubscription.Price * Convert.ToDecimal(0.8));
                subscriber.Subscription = newsubscription;

                EconomicApiLog += "\r\n" + "Abonnent ændret";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);
            }
            catch (Exception ex)
            {

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        //public void CreateSubscriptionInvoice(int InvoiceId, int CustomerId, int EconomicProductNumber, decimal? SpecialSalesPrice, bool BookInvoice)
        public string CreateSubscriptionInvoice(TireServiceDB db, int CustomerId, CustomerSubscription customersubscription, decimal? SpecialSalesPrice)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Invoice, (int)Shared.EconomicInterfaceActions.CreateObject, null, null);
                //int QueueId = UpdateInterfaceQueue(Shared.EconomicInterfaceObjects.Invoice, Shared.EconomicInterfaceActions.CreateObject, InvoiceId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(CustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";
                
                // Get product
                IProduct product = _session.Product.FindByNumber(Convert.ToInt32(db.GetSubscriptionEconomicProductNumber(customersubscription.SubscriptionId)).ToString());
                EconomicApiLog += "\r\n" + "Produkt hentet";

                // Create invoice
                ICurrentInvoice invoice = _session.CurrentInvoice.Create(debtor);
                EconomicApiLog += "\r\n" + "Faktura header oprettet";

                // Create invoice line
                ICurrentInvoiceLine invoiceline = _session.CurrentInvoiceLine.Create(invoice);
                if (customersubscription.SubscriptionId == 4)
                {
                    invoiceline.Description = product.Name;
                }
                else
                {
                    invoiceline.Description = product.Name + (" Abonnement: " + customersubscription.CustomerId.ToString() + "-" + customersubscription.SubscriptionId.ToString() + "-" + customersubscription.CustomerSubscriptionId.ToString());
                }
                invoiceline.Product = product;
                invoiceline.Quantity = 1;
                invoiceline.UnitNetPrice = (SpecialSalesPrice * Convert.ToDecimal(0.8)) ?? product.SalesPrice;

                EconomicApiLog += "\r\n" + "Fakturalinje tilføjet";

                // Book invoice
                IInvoice bookedinvoice = invoice.Book();
                EconomicApiLog += "\r\n" + "Faktura bogført";

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);

                return bookedinvoice.Number.ToString();
            }
            catch (Exception ex)
            {
                return null;   
                
            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        public string CreateSubscriptionRenewalInvoice(TireServiceDB db, int CustomerId, Subscription subscription, CustomerSubscription customersubscription, Car car, bool BookInvoice)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Invoice, (int)Shared.EconomicInterfaceActions.CreateObject, null, null);
                //int QueueId = UpdateInterfaceQueue(Shared.EconomicInterfaceObjects.Invoice, Shared.EconomicInterfaceActions.CreateObject, InvoiceId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                CustomerBLL customerBLL = new CustomerBLL();
                int PayingCustomerId = customerBLL.GetPayingCustomerId(db, CustomerId);
                IDebtor debtor = _session.Debtor.FindByNumber(PayingCustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Create invoice
                ICurrentInvoice invoice = _session.CurrentInvoice.Create(debtor);
                EconomicApiLog += "\r\n" + "Faktura header oprettet";

                // Create invoice line
                CreateSubscriptionInvoiceLine(_session, subscription, customersubscription, car, invoice);

                string Number = "";

                // Book invoice
                if (BookInvoice)
                {
                    IInvoice bookedinvoice = invoice.Book();
                    EconomicApiLog += "\r\n" + "Faktura bogført";

                    Number = bookedinvoice.Number.ToString();
                }
                else
                {
                    // Add other reference (customersubscriptionid) to be able to identify Invoice draft in E-conomic
                    invoice.OtherReference = customersubscription.CustomerSubscriptionId.ToString();
                    EconomicApiLog += "\r\n" + "Faktura oprettet";

                    Number = customersubscription.CustomerSubscriptionId.ToString();
                }
                
                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);

                return Number;
            }
            catch (Exception ex)
            {
                return null;

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        private void CreateSubscriptionInvoiceLine(EconomicSession session, Subscription subscription, CustomerSubscription customersubscription, Car car, ICurrentInvoice invoice)
        {
            ICurrentInvoiceLine invoiceline = session.CurrentInvoiceLine.Create(invoice);

            // Get product
            IProduct product = session.Product.FindByNumber(subscription.EconomicProductNumber.ToString());
            EconomicApiLog += "\r\n" + "Produkt hentet";

            if (customersubscription.SubscriptionId == 4)
            {
                invoiceline.Description = product.Name + "\r\nPakke: " + subscription.Description;
            }
            else
            {
                invoiceline.Description = product.Name + "\r\nPakke: " + subscription.Description + "(" + customersubscription.LastRenewalDate.ToShortDateString() + " - " + customersubscription.NextRenewalDate.ToShortDateString() + ")" + "\r\nNr: " + customersubscription.CustomerId.ToString() + "-" + customersubscription.SubscriptionId.ToString() + "-" + customersubscription.CustomerSubscriptionId.ToString() + "\r\nBil: " + car.RegistrationNumber;
                if (car.CustomerReferenceNumber != string.Empty)
                {
                    invoiceline.Description += "\r\nKunde reference nr: " + car.CustomerReferenceNumber;
                }
            }
            invoiceline.Product = product;
            invoiceline.Quantity = subscription.ServiceDrivesIncluded;

            // Calculate unit/quantity price
            decimal unitprice = 0;
            if (subscription.ExcludeVAT)
            {
                unitprice = customersubscription.Price / subscription.ServiceDrivesIncluded;
            }
            else
            {
                // TODO: Senere skal der kunne tages højde for forskellige moms koder...
                unitprice = customersubscription.Price * Convert.ToDecimal(0.8) / subscription.ServiceDrivesIncluded;
            }

            invoiceline.UnitNetPrice = unitprice;
            EconomicApiLog += "\r\n" + "Fakturalinje tilføjet";
        }

        public string CreateInvoice(TireServiceDB db, int CustomerId, Car car, List<EcoOrderLine> orderlines, bool BookInvoice)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Invoice, (int)Shared.EconomicInterfaceActions.CreateObject, null, null);
                //int QueueId = UpdateInterfaceQueue(Shared.EconomicInterfaceObjects.Invoice, Shared.EconomicInterfaceActions.CreateObject, InvoiceId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                CustomerBLL customerBLL = new CustomerBLL();
                int PayingCustomerId = customerBLL.GetPayingCustomerId(db, CustomerId);
                IDebtor debtor = _session.Debtor.FindByNumber(PayingCustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Create invoice
                ICurrentInvoice invoice = _session.CurrentInvoice.Create(debtor);
                EconomicApiLog += "\r\n" + "Faktura header oprettet";

                // Create needed invoice lines
                foreach (EcoOrderLine orderline in orderlines)
                {
                    if (orderline.CustomerSubscriptionId != null)
                    {
                        // Subscription orderline
                        CustomerSubscription customersubscription = db.GetCustomerSubscription(Convert.ToInt32(orderline.CustomerSubscriptionId));
                        Subscription subscription = db.GetSubscription(customersubscription.SubscriptionId);
                        
                        CreateSubscriptionInvoiceLine(_session, subscription, customersubscription, car, invoice);

                    }
                    else
                    {
                        CreateInvoiceLine(_session, invoice, orderline);
                    }
                }

                string Number = "";

                // Book invoice
                if (BookInvoice)
                {
                    IInvoice bookedinvoice = invoice.Book();
                    EconomicApiLog += "\r\n" + "Faktura bogført";

                    Number = bookedinvoice.Number.ToString();
                }
                else
                {
                    // Add other reference (customersubscriptionid) to be able to identify Invoice draft in E-conomic
                    invoice.OtherReference = car.CustomerSubscriptionId.ToString();
                    EconomicApiLog += "\r\n" + "Faktura oprettet";

                    Number = car.CustomerSubscriptionId.ToString();
                }
                
                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);

                return Number;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;
                return null;

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        public string CreateInvoice(TireServiceDB db, int CustomerId, List<EcoOrderLine> orderlines, bool BookInvoice)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // Create EconomicInterfaceQueue record
                int QueueId = UpdateInterfaceQueue((int)Shared.EconomicInterfaceObjects.Invoice, (int)Shared.EconomicInterfaceActions.CreateObject, null, null);
                //int QueueId = UpdateInterfaceQueue(Shared.EconomicInterfaceObjects.Invoice, Shared.EconomicInterfaceActions.CreateObject, InvoiceId, null);

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                CustomerBLL customerBLL = new CustomerBLL();
                int PayingCustomerId = customerBLL.GetPayingCustomerId(db, CustomerId);
                IDebtor debtor = _session.Debtor.FindByNumber(PayingCustomerId.ToString());
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Create invoice
                ICurrentInvoice invoice = _session.CurrentInvoice.Create(debtor);
                EconomicApiLog += "\r\n" + "Faktura header oprettet";

                // String used to store Car in for each orderline related to a car
                string TempCarRefNumber = "";

                // Create needed invoice lines
                foreach (EcoOrderLine orderline in orderlines)
                {
                    if (orderline.CustomerSubscriptionId != null)
                    {
                        // Subscription orderline
                        CustomerSubscription customersubscription = db.GetCustomerSubscription(Convert.ToInt32(orderline.CustomerSubscriptionId));
                        Subscription subscription = db.GetSubscription(customersubscription.SubscriptionId);

                        List<Car> cars = db.GetCarByCustomerSubscriptionId(Convert.ToInt32(orderline.CustomerSubscriptionId));

                        if (cars == null | cars.Count > 1)
                        {
                            throw new ArgumentException("Faktura oprettelse kan ikke gennemføres grundet ingen bil eller for mange biler påført abonnement.");
                        }
                        else
                        {
                            CreateSubscriptionInvoiceLine(_session, subscription, customersubscription, cars.First(), invoice);

                            TempCarRefNumber += customersubscription.CustomerSubscriptionId.ToString() + ", ";
                        }
                    }
                    else
                    {
                        CreateInvoiceLine(_session, invoice, orderline);
                    }
                }

                string Number = "";

                // Book invoice
                if (BookInvoice)
                {
                    IInvoice bookedinvoice = invoice.Book();
                    EconomicApiLog += "\r\n" + "Faktura bogført";

                    Number = bookedinvoice.Number.ToString();
                }
                else
                {
                    // Add other reference (customersubscriptionid) to be able to identify Invoice draft in E-conomic
                    invoice.OtherReference = TempCarRefNumber; // car.CustomerSubscriptionId.ToString();
                    EconomicApiLog += "\r\n" + "Faktura oprettet";

                    Number = TempCarRefNumber; //car.CustomerSubscriptionId.ToString();
                }

                // Mark interface queue as run with ApiLog as note
                InterfaceQueueCompleted(QueueId, EconomicApiLog);

                return Number;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;
                return null;

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        private void CreateInvoiceLine(EconomicSession session, ICurrentInvoice invoice, EcoOrderLine orderline)
        {
            // Get product
            IProduct product = session.Product.FindByNumber(orderline.ProductNumber.ToString());
            EconomicApiLog += "\r\n" + "Produkt hentet";

            // Create invoice line
            ICurrentInvoiceLine invoiceline = session.CurrentInvoiceLine.Create(invoice);

            invoiceline.Description = orderline.Description;
            invoiceline.Product = product;
            invoiceline.Quantity = orderline.Quantity;
            invoiceline.UnitNetPrice = orderline.UnitPrice;

            EconomicApiLog += "\r\n" + "Fakturalinje tilføjet";
        }


        public void CashbookInvoice(int InvoiceId, int ContraAccount, int CashBookNumber)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                // get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // get the invoice from e-conomic
                IInvoice invoice = _session.Invoice.FindByNumber(InvoiceId);

                // get cashbook and contraaccount from e-conomic
                //ICashBook cashBook = _session.CashBook.GetAll()[0];
                ICashBook cashBook = _session.CashBook.FindByNumber(CashBookNumber);
                IAccount contraAccount = _session.Account.FindByNumber(ContraAccount);

                // create a debtorpayment for the invoice
                ICashBookEntryData cashBookEntryData = _session.CashBookEntryData.Create(CashBookEntryType.DebtorPayment, cashBook, invoice.Debtor, null, null, contraAccount);
                cashBookEntryData.Date = DateTime.Today;
                cashBookEntryData.VoucherNumber = (new Random().Next(1000000)) + 1;
                cashBookEntryData.Currency = _session.Currency.FindByCode("DKK");
                cashBookEntryData.Amount = -invoice.GrossAmount;
                cashBookEntryData.AmountDefaultCurrency = -invoice.GrossAmount;
                cashBookEntryData.Text = "Betaling, Faktura: " + invoice.Number;
                ICashBookEntry entry = _session.CashBookEntry.CreateFromData(cashBookEntryData);
                entry.DebtorInvoiceNumber = invoice.Number;                
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

            }
            finally
            {
                //always disconnect after we are finished.
                Disconnect();
            }
        }

        public List<IInvoiceLine> GetInvoiceLines(int EconomicInvoiceNumber, int CustomerId)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Debtor.FindByNumber(CustomerId.ToString()).GetInvoices().SingleOrDefault(p => p.Number == EconomicInvoiceNumber);
                EconomicApiLog += "\r\n" + "Faktura fundet";

                List<IInvoiceLine> invoicelines = invoice.GetLines().ToList();
                EconomicApiLog += "\r\n" + "Fakturalinjer fundet";

                return invoicelines;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally 
            {
                // disconnect
                Disconnect();
            }
        }

        public List<IInvoiceLine> GetInvoiceLines(int EconomicInvoiceNumber)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
                EconomicApiLog += "\r\n" + "Faktura fundet";

                List<IInvoiceLine> invoicelines = invoice.GetLines().ToList();
                EconomicApiLog += "\r\n" + "Fakturalinjer fundet";

                return invoicelines;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public bool InvoiceLinesExists(int InvoiceId, int CustomerId)
        {
            List<IInvoiceLine> lines = GetInvoiceLines(InvoiceId, CustomerId);

            if (lines == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public bool InvoiceLinesExists(int InvoiceId)
        {
            List<IInvoiceLine> lines = GetInvoiceLines(InvoiceId);

            if (lines == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public int GetCustomerIdByInvoice(int EconomicInvoiceNumber)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
                EconomicApiLog += "\r\n" + "Faktura fundet";

                return Convert.ToInt32(invoice.Debtor.Number);
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return 0;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public decimal? GetInvoiceRemainder(int EconomicInvoiceNumber, int CustomerId)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Debtor.FindByNumber(CustomerId.ToString()).GetInvoices().SingleOrDefault(p => p.Number == EconomicInvoiceNumber);
                EconomicApiLog += "\r\n" + "Faktura fundet";

                return invoice.Remainder;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally 
            {
                // disconnect
                Disconnect();
            }
        }

        public decimal? GetInvoiceRemainder(int EconomicInvoiceNumber)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
                EconomicApiLog += "\r\n" + "Faktura fundet";

                return invoice.Remainder;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public byte[] GetInvoice(int EconomicInvoiceNumber)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
                byte[] invoicebyte = invoice.GetPdf();
                EconomicApiLog += "\r\n" + "Faktura fundet";

                return invoicebyte;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public byte[] GetInvoice(int EconomicInvoiceNumber, int CustomerId)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                // connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                IInvoice invoice = _session.Debtor.FindByNumber(CustomerId.ToString()).GetInvoices().SingleOrDefault(p => p.Number == EconomicInvoiceNumber);
                byte[] invoicebyte = invoice.GetPdf();
                EconomicApiLog += "\r\n" + "Faktura fundet";

                return invoicebyte;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public Stream GetInvoiceStream(int EconomicInvoiceNumber)
        {
            // Start session
            _session = new EconomicSession();

            //connect
            string connectMessage = Connect();
            EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

            IInvoice myInvoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
            Stream file = new MemoryStream(myInvoice.GetPdf());

            return file;
        }

        public Stream GetInvoiceStream(int EconomicInvoiceNumber, int CustomerId)
        {
            // Start session
            _session = new EconomicSession();

            //connect
            string connectMessage = Connect();
            EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

            IInvoice invoice = _session.Debtor.FindByNumber(CustomerId.ToString()).GetInvoices().SingleOrDefault(p => p.Number == EconomicInvoiceNumber);
            Stream file = new MemoryStream(invoice.GetPdf());

            return file;
        }

        //public Stream ReadInvoice(int EconomicInvoiceNumber)
        //{

        //    // Start session
        //    _session = new EconomicSession();

        //    // connect
        //    string connectMessage = Connect();
        //    EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

        //    IInvoice invoice = _session.Invoice.FindByNumber(EconomicInvoiceNumber);
        //    byte[] file = invoice.GetPdf();
        //    EconomicApiLog += "\r\n" + "Faktura fundet";

        //    MemoryStream readfile = new MemoryStream();
        //    readfile.Write(file, 0, file.Length);
        //    readfile.Position = 0;

        //    // disconnect
        //    Disconnect();

        //    return readfile;
        //}

        public List<EcoInvoice> GetCustomerInvoiceList(int CustomerId)
        {
            try
            {
                // Start session
                _session = new EconomicSession();

                //connect
                string connectMessage = Connect();
                EconomicApiLog += "Connection Success. Connection UniqueID: " + connectMessage;

                //get API version.
                EconomicApiLog += "\r\n" + "API version: " + _session.GetApiInformation();

                // Get debtor
                IDebtor debtor = _session.Debtor.FindByNumber(CustomerId.ToString());
                if (debtor == null) return null;
                EconomicApiLog += "\r\n" + "Debitor hentet";

                // Get invoices for debtor
                List<IInvoice> invoices = debtor.GetInvoices().ToList();

                List<EcoInvoice> ecoinvoices = new List<EcoInvoice>();

                foreach (IInvoice invoice in invoices)
                {
                    EcoInvoice ecoinvoice = new EcoInvoice();
                    ecoinvoice.Number = invoice.Number;
                    ecoinvoice.Date = invoice.Date;
                    ecoinvoice.DueDate = invoice.DueDate;
                    ecoinvoice.GrossAmount = invoice.GrossAmount;
                    ecoinvoice.Remainder = invoice.Remainder;

                    ecoinvoices.Add(ecoinvoice);
                }

                return ecoinvoices;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public List<EcoInvoiceLine> GetCustomerInvoiceLineList(int InvoiceId, int CustomerId)
        {
            try
            {
                // Get invoicelines for debtor
                List<IInvoiceLine> lines = GetInvoiceLines(InvoiceId, CustomerId);

                List<EcoInvoiceLine> ecoinvoicelines = new List<EcoInvoiceLine>();

                foreach (IInvoiceLine line in lines)
                {
                    EcoInvoiceLine ecoinvoiceline = new EcoInvoiceLine();
                    ecoinvoiceline.Number = line.Number;
                    ecoinvoiceline.Description = line.Description;
                    ecoinvoiceline.Quantity = line.Quantity;
                    ecoinvoiceline.UnitNetPrice = line.UnitNetPrice;
                    ecoinvoiceline.TotalNetAmount = line.TotalNetAmount;
                    ecoinvoiceline.VatAmount = line.VatAmount;

                    ecoinvoicelines.Add(ecoinvoiceline);
                }

                return ecoinvoicelines;
            }
            catch (Exception ex)
            {
                EconomicApiLog += "Fejl opstod: " + ex.Message;

                return null;
            }
            finally
            {
                // disconnect
                Disconnect();
            }
        }

        public void CustomerEntry(int CustomerId)
        {
            IDebtorEntry[] entries = _session.Debtor.FindByNumber(CustomerId.ToString()).GetOpenEntries();

            foreach (IDebtorEntry entry in entries)
            {
                    
            }
            
        }

        public class EcoOrderLine
        {
            private int _productnumber;
            private string _description;
            private decimal _quantity;
            private decimal _unitprice;
            private int? _customersubscriptionid;

            public int ProductNumber
            {
                get
                {
                    return this._productnumber;
                }
                set
                {
                    this._productnumber = value;
                }
            }

            public string Description
            {
                get
                {
                    return this._description;
                }
                set
                {
                    this._description = value;
                }
            }

            public decimal Quantity
            {
                get
                {
                    return this._quantity;
                }
                set
                {
                    this._quantity = value;
                }
            }

            public decimal UnitPrice
            {
                get
                {
                    return this._unitprice;
                }
                set
                {
                    this._unitprice = value;
                }
            }

            public int? CustomerSubscriptionId
            {
                get
                {
                    return this._customersubscriptionid;
                }
                set
                {
                    this._customersubscriptionid = value;
                }
            }
        }

        public class EcoInvoice
        { 
            private int _number;
            private DateTime _date;
            private DateTime _duedate;
            private decimal _grossamount;
            private decimal _remainder;

            public int Number
            {
                get 
                { 
                    return this._number; 
                }
                set
                {
                    this._number = value;
                }
            }

            public DateTime Date
            {
                get
                {
                    return this._date;
                }
                set
                {
                    this._date = value;
                }
            }

            public DateTime DueDate
            {
                get
                {
                    return this._duedate;
                }
                set
                {
                    this._duedate = value;
                }
            }

            public decimal GrossAmount
            {
                get
                {
                    return this._grossamount;
                }
                set
                {
                    this._grossamount = value;
                }
            }

            public decimal Remainder
            {
                get
                {
                    return this._remainder;
                }
                set
                {
                    this._remainder = value;
                }
            }
        }

        public class EcoInvoiceLine
        {
            private int _number;
            private string _description;
            private decimal _quantity;
            private decimal _unitnetprice;
            private decimal _totalnetamount;
            private decimal _vatamount;

            public int Number
            {
                get
                {
                    return this._number;
                }
                set
                {
                    this._number = value;
                }
            }

            public string Description
            {
                get
                {
                    return this._description;
                }
                set
                {
                    this._description = value;
                }
            }

            public decimal Quantity
            {
                get
                {
                    return this._quantity;
                }
                set
                {
                    this._quantity = value;
                }
            }

            public decimal UnitNetPrice
            {
                get
                {
                    return this._unitnetprice;
                }
                set
                {
                    this._unitnetprice = value;
                }
            }

            public decimal TotalNetAmount
            {
                get
                {
                    return this._totalnetamount;
                }
                set
                {
                    this._totalnetamount = value;
                }
            }

            public decimal VatAmount
            {
                get
                {
                    return this._vatamount;
                }
                set
                {
                    this._vatamount = value;
                }
            }
        }

    }
}
